package com.linkage.event.service.impl;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.linkage.common.base.RequestInfo;
import com.linkage.common.base.ResponseInfo;
import com.linkage.common.constant.CommonSysConstant;
import com.linkage.common.exception.ServiceException;
import com.linkage.event.contents.EventContents;
import com.linkage.event.feign.usercenter.UserCenterFeign;
import com.linkage.event.feign.usercenter.entity.UserMgInfoVO;
import com.linkage.event.pojo.dao.*;
import com.linkage.event.pojo.entity.*;
import com.linkage.event.pojo.vo.*;
import com.linkage.event.service.EventOperationService;
import com.linkage.event.utils.FileTypeUtil;
import com.linkage.event.utils.UserInterfUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

@Service
@Slf4j
public class EventOperationServiceImpl implements EventOperationService {

    @Autowired
    private EventMessageMapper emMapper;

    @Autowired
    private EventMediaMapper emaMapper;

    @Autowired
    private EventAttentionMapper eaMapper;

    @Autowired
    private EventTaskMapper etMapper;

    @Autowired
    private EventTypeMapper eventTypeMapper;

    @Resource
    private UserCenterFeign userCenterFeign;

    @Resource
    private EventDiscussesMapper eventDiscussesMapper;

    @Override
    @Transactional
    public String createEvent(EventMessage em) {
        em = this.buildEventMessage(em);
        if(StrUtil.isNotEmpty(em.getPicUrlList())){
            List<EventMedia> emas = this.buildEventMedia(em, em.getPicUrlList());
            this.emaMapper.insertBatch(emas);
        }
        log.info("入参："+em.toString());
        this.emMapper.insertSelective(em);
        return em.getId();
    }

    @Override
    public void commitEvent(EventTask eventTask,String userToken) throws Exception {
        if(StrUtil.hasEmpty(eventTask.getEventMsgId(),eventTask.getUserId())){
            throw new ServiceException(500,"事件ID或用户id参数为空");
        }
        //2.依据Userid和EventId查询任务表:修改原数据，将处理人解决状态修改为2：已提交
        EventTask taskInfo = etMapper.selectByPrimaryKey(EventTask.builder().eventMsgId(eventTask.getEventMsgId()).userId(eventTask.getUserId()).solveStatus("2").build());
        if (taskInfo == null){
            eventTask.setSolveStatus("2");
            eventTask.setIsIdentity("0");
            this.etMapper.insertSelective(eventTask);
        }
        //1,依据Userid查询此人上级的UserId
        UserMgInfoVO userMgInfoVO = this.feignSuperiorManager(eventTask,userToken);
        if(null == userMgInfoVO){
            throw new ServiceException(500,"未查询到对应管理员，无法提交！");
        }
        String bossUserId = userMgInfoVO.getUserCode();
        String departmentId = userMgInfoVO.getPersonOrgCode();
        //3.新增一条数据
        EventTask newEventTask = new EventTask();
        newEventTask.setEventMsgId(eventTask.getEventMsgId());
        newEventTask.setUserId(bossUserId);
        newEventTask.setSolveStatus("0");
        EventTask task = etMapper.selectByPrimaryKey(newEventTask);
        if(task == null){
            newEventTask.setDepartmentId(departmentId);
            newEventTask.setSolveStatus("0");
            newEventTask.setIsIdentity("1");
            this.etMapper.insertSelective(newEventTask);
        }
        //修改当前事件状态为已提交
        emMapper.updateByPrimaryKeySelective(EventMessage.builder().id(eventTask.getEventMsgId()).eventCommitStatus("1").build());
    }

    @Override
    public void designateEvent(String eventMsgId, List<String> designateUserIds,String token) throws Exception {
        //2.批量新增数据
        for(String designateUserId : designateUserIds){
            EventTask eventTask = new EventTask();
            eventTask.setEventMsgId(eventMsgId);
            eventTask.setUserId(designateUserId);
            eventTask.setSolveStatus("0");
            EventTask isExist = etMapper.selectByPrimaryKey(eventTask);
            if(isExist == null){
                eventTask.setSolveStatus("0");
                eventTask.setIsIdentity("2");
                this.etMapper.insertSelective(eventTask);
            }
        }
        //更新处理人状态
        String[] usertoken = token.split(":");
        String userCode = usertoken[usertoken.length-1];
        etMapper.updateByPrimaryKeySelective(EventTask.builder().eventMsgId(eventMsgId).userId(userCode).solveStatus("1").build());
        //更新事件状态为已派发
        emMapper.updateByPrimaryKeySelective(EventMessage.builder().id(eventMsgId).eventDisposeStatus("2").build());
    }


    @Override
    public void updateEventTaskByPrimaryKeySelective(EventTask record) throws Exception {
        if(StrUtil.hasEmpty(record.getEventMsgId(),record.getUserId())){
            throw new ServiceException(500,"事件id或用户id为空");
        }
        EventTask task = etMapper.selectByPrimaryKey(EventTask.builder().eventMsgId(record.getEventMsgId()).userId(record.getUserId()).solveStatus("0").build());
        if(null == task){
            throw new ServiceException(500,"处理事件流程不存在");
        }
        record.setSolveStatus("1");
        record.setDealTime(System.currentTimeMillis());
        this.etMapper.updateByPrimaryKeySelective(record);
        List<EventTask> list = etMapper.selectByEventMsgId(record.getEventMsgId(),"2");
        List<String> statusList = list.stream().map(EventTask::getSolveStatus).collect(Collectors.toList());
        if(!statusList.contains("0")){
            this.emMapper.updateByPrimaryKeySelective(EventMessage.builder().id(record.getEventMsgId()).eventDisposeStatus("1").build());
        }
    }

    @Override
    public EventShowVo singleEventShow(String eventMessageId){
        EventShowVo esv = new EventShowVo();
        //1.通过事件Id查询事件
        EventMessage em = this.emMapper.selectByPrimaryKey(eventMessageId);
        esv.setEm(em);
        //2.通过事件Id查询图片信息
        List<EventMedia> emas = this.emaMapper.selectByEventMessagePrimaryKey(eventMessageId);
        esv.setEmas(emas);
        return esv;
    }

    @Override
    public PageInfo<EventMessageVo> listEventShow(Integer pageNo, Integer pageSize, EventMessage eventMessage, String startDate, String endDate, String userToken) throws Exception {
        List<String> userList  = null;
        if(StrUtil.isNotEmpty(userToken)){
            String role = userToken.split(":")[2];
            if(!"CJGLY-3".equals(role)){
                String dptCode = userToken.split(":")[1];
                // 查询所有下级成员
                List<UserMgInfoVO> list = UserInterfUtils.getUserListLocations(dptCode,userToken);
                if(ObjectUtil.isEmpty(list)){
                    return new PageInfo<EventMessageVo>(new ArrayList<>());
                }
                userList = list.stream().map(UserMgInfoVO::getUserCode).collect(Collectors.toList());
            }
        }
        Integer flag = null;
        if(StrUtil.isNotEmpty(eventMessage.getEventType())){
            //校验是否为一级目录
            EventType eventType = eventTypeMapper.selectByPrimaryKey(eventMessage.getEventType());
            flag = 1;
            if(null != eventType && StrUtil.equals("0",eventType.getSuperiorTypeCode())){
                flag = 0;
            }
        }
        if(null != pageNo && null != pageSize){
            PageHelper.startPage(pageNo, pageSize);
        }
        EventMessage message = new EventMessage();
        message.setEventDisposeStatus(eventMessage.getEventDisposeStatus());
        message.setEventType(eventMessage.getEventType());
        message.setEventTitle(eventMessage.getEventTitle());
        message.setRecommendStatus(eventMessage.getRecommendStatus());
        message.setTrainingType(eventMessage.getTrainingType());
        Date startTime = StrUtil.isEmpty(startDate)? null : DateUtil.parseDateTime(startDate);
        message.setCreateTime(startTime);
        Date endTime = StrUtil.isEmpty(endDate)? null : DateUtil.parseDateTime(endDate);
        List<EventMessage> eventMessages = this.emMapper.selectByEventList(message, endTime,userList,flag);
        PageInfo pageInfo = new PageInfo<>(eventMessages);
        List<EventMessageVo> result = new ArrayList<>();
        //处理返参信息，包括处理人列表，事件提交人信息
        eventMessages.forEach(x ->{
            EventMessageVo vo = new EventMessageVo();
            //查询关联人
            List<EventTask> taskList = etMapper.selectByEventMsgId(x.getId(),"2");
            List<TaskVo> taskVos = new ArrayList<>();
            for(EventTask task : taskList){
                UserMgInfoVO userMgInfoVO = getUserInfo(task.getUserId(),userToken);
                if(ObjectUtil.isNotNull(userMgInfoVO)){
                    String dealTime = null;
                    if(task.getDealTime() != null){
                        dealTime = DateUtil.format(new Date(task.getDealTime()),"yyyy-MM-dd HH:mm:ss");
                    }
                    taskVos.add(TaskVo.builder().avatar(userMgInfoVO.getUserPhotoUrl()).isCommit(task.getSolveStatus())
                            .userCode(userMgInfoVO.getUserCode()).userName(userMgInfoVO.getUserRealName())
                            .dealLocation(task.getDealLocation()).remark(task.getRemark())
                            .dealTime(dealTime).build());
                }
            }
            vo.setEventTask(taskVos);
            UserMgInfoVO userMgInfoVO = getUserInfo(x.getEventAuthorId(),userToken);
            if(null == userMgInfoVO){
                vo.setUserVo(null);
            }else{
                vo.setUserVo(UserVo.builder()
                        .phone(userMgInfoVO.getUserMobile()).userCode(userMgInfoVO.getUserCode())
                        .userName(userMgInfoVO.getUserRealName()).userPhotoUrl(userMgInfoVO.getUserPhotoUrl()).build());
            }
            vo.setEventMessage(x);
            result.add(vo);
        });
        pageInfo.setList(result);
        return pageInfo;
    }

    @Override
    public List<EventType> selectBySuperiorTypeCode(String superiorTypeCode,String status) throws Exception {
        return this.eventTypeMapper.selectBySuperiorTypeCode(superiorTypeCode,status);
    }

    @Override
    public EventType selectByEventTypePrimaryKey(String eventTypeCode) {
        return this.eventTypeMapper.selectByPrimaryKey(eventTypeCode);
    }


    @Override
    public List<EventTask> selectEventTaskByEventMsgId(String eventMsgId) throws Exception {
        return this.etMapper.selectByEventMsgId(eventMsgId,"2");
    }

    @Override
    public Map<String, Integer> statisticEventCount(String userCode,String token) {
        String dptCode = null;
        if(userCode != null){
            dptCode = getDptCodeByUserCode(userCode,token);
        }
        //根据事件状态统计事件数量
        List<Map<String, Object>> statusMap = emMapper.statisticEventCountByStatus(dptCode);
        //根据事件类型统计事件数量
        List<Map<String, Object>> typeUnsolvedMap = emMapper.statisticEventCountByType(dptCode,"0");
        List<Map<String, Object>> typeSolvedMap = emMapper.statisticEventCountByType(dptCode,"1");
        //人防未解决事件数
        Long personUnresolved = 0l;
        //技防未解决事件数
        Long techUnresolved = 0l;
        //人防解决事件数
        Long personResolved = 0l;
        //技防解决事件数
        Long techResolved =0l;
        for(Map map : typeUnsolvedMap){
            if("EVENT_TYPE_1".equals(map.get("type"))){
                personUnresolved = (Long)map.get("count");
            }
            if("EVENT_TYPE_2".equals(map.get("type"))){
                techUnresolved = (Long)map.get("count");
            }
        }
        for(Map map : typeSolvedMap){
            if("EVENT_TYPE_1".equals(map.get("type"))){
                personResolved = (Long)map.get("count");
            }
            if("EVENT_TYPE_2".equals(map.get("type"))){
                techResolved = (Long)map.get("count");
            }
        }
        //未解决事件数
        Long unresolved = 0l;
        //解决事件数
        Long resolved = 0l;
        for(Map map : statusMap){
            if("0".equals(map.get("type"))){
                unresolved = (Long)map.get("count");
            }
            if("1".equals(map.get("type"))){
                resolved = (Long)map.get("count");
            }
        }
        List<Map> mapList = eventDiscussesMapper.selectStatusCountByDate(null,null);
        Map<String,Object> resultMap = new HashMap<>(4);
        //群众已解决
        Long qzResolve = 0l;
        //群众未解决
        Long qzUnsolve = 0l;
        for(Map<String, Object> map : mapList){
            if(StrUtil.equals("1",map.get("type").toString())){
                qzResolve = (long)map.get("count");
            }
            if(StrUtil.equals("0",map.get("type").toString())){
                qzUnsolve = (long)map.get("count");
            }
        }
        Map<String, Integer> result = new HashMap<>();
        result.put("qzResolve",qzResolve.intValue());
        result.put("qzUnsolve",qzUnsolve.intValue());
        result.put("unresolved",unresolved.intValue());
        result.put("resolved",resolved.intValue());
        result.put("personUnresolved",personUnresolved.intValue());
        result.put("techUnresolved",techUnresolved.intValue());
        result.put("personResolved",personResolved.intValue());
        result.put("techResolved",techResolved.intValue());
        return result;
    }

    @Override
    public List<Map<String,Object>> statisticEventCountByPersonClass(String personClass, String userCode, String token){
        List<Map<String,Object>> result = new ArrayList<>();
        //如果查询群众，则查询
        if(StrUtil.equals("0",personClass)){
            for(int i = 0 ; i<8;i++){
                String startTime = DateUtil.beginOfMonth(DateUtil.offsetMonth(new Date(),-i)).toString();
                String endTime = DateUtil.endOfMonth(DateUtil.offsetMonth(new Date(),-i)).toString();
                List<Map> mapList = eventDiscussesMapper.selectStatusCountByDate(startTime,endTime);
                Map<String,Object> resultMap = new HashMap<>(4);
                Long resolve = 0l;
                Long unsolve = 0l;
                for(Map<String, Object> map : mapList){
                    if(StrUtil.equals("1",map.get("type").toString())){
                        resolve = (long)map.get("count");
                    }
                    if(StrUtil.equals("0",map.get("type").toString())){
                        unsolve = (long)map.get("count");
                    }
                }
                //全部事件数
                resultMap.put("total",resolve+unsolve);
                //已解决事件
                resultMap.put("resolve",resolve);
                //未解决事件
                resultMap.put("unsolve",unsolve);
                resultMap.put("month",DateUtil.offsetMonth(new Date(),-i).toString("yyyyMM"));
                result.add(resultMap);
            }
        }else {
            String dptCode = null;
            if (userCode != null){
                dptCode = getDptCodeByUserCode(userCode,token);
            }else{
                personClass = "0";
            }
            for (int i = 0 ; i<8;i++){
                String startTime = DateUtil.beginOfMonth(DateUtil.offsetMonth(new Date(),-i)).toString();
                String endTime = DateUtil.endOfMonth(DateUtil.offsetMonth(new Date(),-i)).toString();
                List<Map<String, Object>> typeMap = emMapper.statisticEventCountByRole(personClass,dptCode,startTime,endTime);
                Map<String,Object> resultMap = new HashMap<>(4);
                Long resolve = 0l;
                Long unsolve = 0l;
                for(Map<String, Object> map : typeMap){
                    if(StrUtil.equals("1",String.valueOf(map.get("status")))){
                        resolve = (long)map.get("count");
                    }
                    if(StrUtil.equals("0",String.valueOf(map.get("status")))){
                        unsolve = (long)map.get("count");
                    }
                }
                resultMap.put("total",resolve+unsolve);
                resultMap.put("resolve",resolve);
                resultMap.put("unsolve",unsolve);
                resultMap.put("month",DateUtil.offsetMonth(new Date(),-i).toString("yyyyMM"));
                result.add(resultMap);
            }
        }
        return result;
    }

    @Override
    public PageInfo<EventMessage> queryListByPage(Integer page, Integer pageSize, EventTask eventTask, String eventDisposeStatus){
        if(ObjectUtil.isNull(page)){
            page = EventContents.DEFAULT_PAGE_NO;
        }
        if(ObjectUtil.isNull(pageSize)){
            pageSize = EventContents.DEFAULT_PAGE_SIZE;
        }
        if(StrUtil.isEmpty(eventTask.getUserId())){
            throw new ServiceException(500,"UserId 数据为空");
        }
        if(StrUtil.isEmpty(eventTask.getSolveStatus())){
            throw new ServiceException(500,"solveStatus 数据为空");
        }
        String flag = "1";
        //我的提交，已处理
        if(StrUtil.equals("3",eventTask.getSolveStatus())){
            flag = "0";
            eventTask.setSolveStatus("2");
            eventTask.setEventAuthorId(eventTask.getUserId());
            eventTask.setUserId(eventTask.getUserId());
        }
        //我的提交-未处理
        else if(StrUtil.equals("2",eventTask.getSolveStatus())){
            flag = "0";
            eventTask.setEventAuthorId(eventTask.getUserId());
            eventTask.setUserId(eventTask.getUserId());
            eventTask.setSolveStatus("2");
        }
        PageHelper.startPage(page, pageSize);
        List<EventMessage> list = emMapper.selectMyEvents(eventTask, eventDisposeStatus,flag);
        //处理返参
        for(EventMessage message : list){
            EventTask et = etMapper.selectByPrimaryKey(EventTask.builder().userId(eventTask.getUserId()).solveStatus("1").eventMsgId(message.getId()).build());
            if(null == et){
                message.setFlag("0");
            }else{
                message.setFlag("1");
            }
            message.setTask(et);
            List<EventMedia> media = emaMapper.selectByEventMessagePrimaryKey(message.getId());
            message.setEventMedia(media);
        }
        return new PageInfo<EventMessage>(list);
    }

    /**
     * 根据用户code查询部门code
     * @param userCode
     * @param token
     * @return
     */
    private String getDptCodeByUserCode(String userCode, String token){
        RequestInfo<Map<String, String>> query = new RequestInfo<>();
        Map<String, String> map = new HashMap<>(1);
        map.put("paramVar",userCode);
        query.setBuss(map);
        query.getBase().setUsertoken(token);
        String response = userCenterFeign.getUserMgInfoVO(query);
        ResponseInfo<UserMgInfoVO> userMgInfoVOResponseInfo = JSON.parseObject(response,ResponseInfo.class);
        UserMgInfoVO buss = JSON.parseObject(String.valueOf(userMgInfoVOResponseInfo.getBuss()),UserMgInfoVO.class);
        if(ObjectUtil.isNull(userMgInfoVOResponseInfo)){
            throw new ServiceException(500,"查询当前登录用户所属部门失败！");
        }
        if(ObjectUtil.isNull(userMgInfoVOResponseInfo.getBuss())){
            throw new ServiceException(500,"查询当前登录用户所属部门失败！");
        }
        if(StrUtil.equals("1",userMgInfoVOResponseInfo.getBase().getSuccessCode())){
            throw new ServiceException(500,"查询当前登录用户所属部门失败！");
        }
        String dptCode = buss.getPersonOrgCode();
        return dptCode;
    }

    private EventMessage buildEventMessage(EventMessage em){
        em.setId(IdUtil.simpleUUID());
        em.setEventDisposeStatus(EventContents.CLOSED);
        em.setReplyEnabledStatus(EventContents.ENABLED);
        em.setDiscussedEnabledStatus(EventContents.ENABLED);
        //培训特殊设置
        if(EventContents.EVENT_TYPE_TRAIN.equals(em.getEventType())){
            em.setEventDisposeStatus(EventContents.STATUS_NO_COMMIT);
            em.setReplyEnabledStatus(EventContents.CLOSED);
            em.setDiscussedEnabledStatus(EventContents.CLOSED);
        }
        em.setEnabledStatus(EventContents.ENABLED);
        em.setCreateTime(new Date());
        em.setModifyTime(new Date());
        return em;
    }

    private List<EventMedia> buildEventMedia(EventMessage em, String imageUrls){
        List<EventMedia> eventMediaList = new LinkedList<>();
        for(String imageUrl : imageUrls.split(",")) {
            if(StrUtil.isEmpty(imageUrl)){
                continue;
            }
            EventMedia ema = new EventMedia();
            ema.setId(IdUtil.simpleUUID());
            ema.setEventMsgId(em.getId());
            ema.setMediaUrl(imageUrl);
            String img = imageUrl.split("\\?")[0];
            ema.setMediaType(FileTypeUtil.getType(img).toString());
            ema.setUserSort(0L);
            ema.setEnabledStatus(EventContents.ENABLED);
            ema.setCreateUserId(em.getEventAuthorId());
            ema.setCreateTime(new Date());
            eventMediaList.add(ema);
        }
        return eventMediaList;
    }

    /**
     * 获取用户信息
     * @param userCode
     * @param userToken
     * @return
     */
    private UserMgInfoVO getUserInfo(String userCode,String userToken){
        RequestInfo<Map<String, String>> query = new RequestInfo<>();
        Map<String, String> map = new HashMap<>(1);
        map.put("paramVar",userCode);
        query.setBuss(map);
        query.getBase().setUsertoken(userToken);
        String response = userCenterFeign.getUserMgInfoVO(query);
        ResponseInfo userMgInfoVOResponseInfo = JSON.parseObject(response,ResponseInfo.class);
        UserMgInfoVO buss = JSON.parseObject(String.valueOf(userMgInfoVOResponseInfo.getBuss()),UserMgInfoVO.class);
        if(ObjectUtil.isNull(userMgInfoVOResponseInfo)){
            return null;
        }
        if(ObjectUtil.isNull(userMgInfoVOResponseInfo.getBuss())){
            return null;
        }
        if(StrUtil.equals("1",userMgInfoVOResponseInfo.getBase().getSuccessCode())){
            return null;
        }
        return buss;
    }

    /**
     * 查询上级管理员信息
     * @param eventTask
     * @param userToken
     * @return
     */
    private UserMgInfoVO feignSuperiorManager(EventTask eventTask, String userToken){
        RequestInfo<Map<String, String>> query = new RequestInfo<>();
        Map<String, String> map = new HashMap<>();
        map.put("userCode",eventTask.getUserId());
        query.setBuss(map);
        query.getBase().setUsertoken(userToken);
        String json = this.userCenterFeign.getSuperiorManager(query);
        JSONObject jsonObject = new JSONObject(json);
        ResponseInfo userMgInfoVOResponseInfo = jsonObject.toBean(ResponseInfo.class);
        if(CommonSysConstant.CODE_ONE.equals(userMgInfoVOResponseInfo.getBase().getSuccessCode())){
            return null;
        }
        log.info(userMgInfoVOResponseInfo.getBuss().toString());
        UserMgInfoVO userMgInfoVO = com.alibaba.fastjson.JSONObject.parseObject(String.valueOf(userMgInfoVOResponseInfo.getBuss()),UserMgInfoVO.class);
        return userMgInfoVO;
    }

}
